home *** CD-ROM | disk | FTP | other *** search
- //
- // This is box, the QuickDraw 3D starter program. Written for the
- // Getting started with QuickDraw 3D Develop article. This app does not have
- // graceful error handling - it's purpose is to illustrate a very basic QuickDraw
- // 3D program.
- //
- // Nick Thompson - January 6th 1994
- //
- // Modification History:
- //
- // 1/6/95 nick initial version based on cube
- // 12/31/94 nick cube modifications for QuickDraw 3d sample code
- // 03/22/95 rdd adapted from BoxShell.c: added simple picking
- // and trigrid selection via number keys
- // 04/12/95 rdd added SetCameraLocation.
- // 04/14/95 rdd added menu support.
- //
-
-
- // system headers
- #include <Desk.h>
- #include <Dialogs.h>
- #include <DiskInit.h>
- #include <Fonts.h>
- #include <Menus.h>
- #include <PictUtil.h>
- #include <QDOffScreen.h>
- #include <QuickDraw.h>
- #include <Resources.h>
- #include <SegLoad.h>
- #include <StandardFile.h>
- #include <TextEdit.h>
- #include <ToolUtils.h>
-
- // for QuickDraw 3D
- #include "QD3D.h"
- #include "QD3DMath.h"
- #include "QD3DCamera.h"
- #include "QD3DDrawContext.h"
- #include "QD3DShader.h"
- #include "QD3DTransform.h"
- #include "QD3DGroup.h"
- #include "QD3DPick.h"
-
-
- #include "TriGridShell.h"
- #include "TriGrid3DSupport.h"
- #include "GeometrySample.h"
- #include "Textures2.h"
-
- //-------------------------------------------------------------------------------------------
-
- struct _documentRecord {
- TQ3ViewObject fView ; // the view for the scene
- TQ3GroupObject fModel ; // object in the scene being modelled
- TQ3StyleObject fInterpolation ; // interpolation style used when rendering
- TQ3StyleObject fBackFacing ; // whether to draw shapes that face away from the camera
- TQ3StyleObject fFillStyle ; // whether drawn as solid filled object or decomposed to components
- TQ3Matrix4x4 fRotation ; // the transform for the model
- unsigned short fGeometryNum ; // triGrid geometry 1-9 (menu item number)
- unsigned short fTextureType ; // method of uv parameterization for texture (menu item number)
- unsigned short fPictureNum ; // PICT (menu item number)
- };
-
- typedef struct _documentRecord DocumentRec, *DocumentPtr, **DocumentHdl ;
-
-
- //-------------------------------------------------------------------------------------------
- // function prototypes
-
- static void InitToolbox( void ) ;
- static Boolean SetUpMenus (void) ;
- static void IntializeMenuItems (DocumentPtr theDocument) ;
- static void MainEventLoop( void ) ;
- static void HandleKeyPress(EventRecord *pEvent) ;
- static void DoAboutBox (void);
- static void DoMenuCommand (long menuResult) ;
- static void HandleOSEvent(EventRecord *event) ;
- static void InitDocumentData( DocumentPtr theDocument ) ;
- static TQ3Status DocumentDraw3DData( DocumentPtr theDocument ) ;
- static void DisposeDocumentData( DocumentPtr theDocument) ;
- static void SetCameraLocation (TQ3ViewObject view, float x, float y, float z);
- static void ChangeGeometry (DocumentPtr theDocument) ;
- static void DoPicking(EventRecord *event) ;
-
-
- //-------------------------------------------------------------------------------------------
- //
-
- Boolean gQuitFlag = false ;
- WindowPtr gMainWindow = nil ;
- DocumentRec gDocument ;
- Handle ghMenuBar ;
- short gNumPictures ;
-
-
- //-------------------------------------------------------------------------------------------
- // main()
- // entry point for the application, initialize the toolbox, initialize QuickDraw 3D
- // and enter the main event loop. On exit from the main event loop, we want to call
- // the QuickDraw 3D exit function to clean up QuickDraw 3d.
-
- void main(void)
- {
- TQ3Status myStatus;
-
- InitToolbox() ;
- SetUpMenus () ;
-
- // Initialize QuickDraw 3D, open a connection to the QuickDraw 3D library
- myStatus = Q3Initialize();
- if ( myStatus == kQ3Failure )
- DebugStr("\pErInitialize returned failure.");
-
- // set up our globals
- gQuitFlag = false ;
- gMainWindow = GetNewCWindow(kWindowRsrcID, nil, (WindowPtr)-1);
-
- InitDocumentData( &gDocument ) ;
- IntializeMenuItems ( &gDocument ) ;
-
- MainEventLoop();
-
- DisposeDocumentData( &gDocument ) ;
-
- // Close our connection to the QuickDraw 3D library
- myStatus = Q3Exit();
- if ( myStatus == kQ3Failure )
- DebugStr("\pErExit returned failure.");
-
- }
-
- //-------------------------------------------------------------------------------------------
- //
-
- void InitDocumentData( DocumentPtr theDocument )
- {
- // sets up the 3d data for the scene
- // Create view for QuickDraw 3D.
- theDocument->fView = MyNewView( (WindowPtr)gMainWindow ) ;
-
- // the drawing styles:
- theDocument->fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ;
- theDocument->fBackFacing = Q3BackfacingStyle_New(kQ3BackfacingStyleBoth ) ;
- theDocument->fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
-
- // set the rotation matrix the identity matrix
- Q3Matrix4x4_SetIdentity(&theDocument->fRotation);
-
- theDocument->fGeometryNum = iFlat ;
- theDocument->fTextureType = iNoTexture ;
- theDocument->fPictureNum = iPictureFirst ;
-
- // the main display group:
- theDocument->fModel = MyNewModel() ;
- ChangeGeometry (theDocument);
- }
-
- void DisposeDocumentData( DocumentPtr theDocument)
- {
-
- if(theDocument->fView)
- Q3Object_Dispose(theDocument->fView) ; // the view for the scene
-
- if(theDocument->fModel)
- Q3Object_Dispose(theDocument->fModel) ; // object in the scene being modelled
-
- if(theDocument->fInterpolation)
- Q3Object_Dispose(theDocument->fInterpolation) ; // interpolation style used when rendering
-
- if(theDocument->fBackFacing)
- Q3Object_Dispose(theDocument->fBackFacing) ; // whether to draw shapes that face away from the camera
-
- if(theDocument->fFillStyle)
- Q3Object_Dispose(theDocument->fFillStyle) ; // whether drawn as solid filled object or decomposed to components
-
- }
- //-----------------------------------------------------------------------------
- //
-
- TQ3Status DocumentDraw3DData( DocumentPtr theDocument )
- {
- Q3View_StartRendering(theDocument->fView );
- do {
- Q3Style_Submit( theDocument->fInterpolation, theDocument->fView );
- Q3Style_Submit( theDocument->fBackFacing, theDocument->fView );
- Q3Style_Submit( theDocument->fFillStyle, theDocument->fView );
- Q3MatrixTransform_Submit( &theDocument->fRotation, theDocument->fView );
- Q3DisplayGroup_Submit( theDocument->fModel, theDocument->fView );
- } while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse );
- return kQ3Success ;
- }
-
-
- //----------------------------------------------------------------------------------
- //
- void InitToolbox()
- {
- Handle menuBar = nil;
-
- MaxApplZone() ;
- MoreMasters() ; MoreMasters() ; MoreMasters() ;
-
- InitGraf( &qd.thePort );
- InitFonts();
- InitWindows();
- InitCursor();
-
- FlushEvents( everyEvent, 0 ) ;
- // initialize application globals
-
- gQuitFlag = false;
-
- }
-
-
- //-------------------------------------------------------------------------------------------
- //
- Boolean SetUpMenus (void)
- {
- Boolean goodMenus;
-
- goodMenus = true;
-
- ghMenuBar = GetNewMBar (kMenuBarRsrc);
- if (ghMenuBar != nil)
- {
- SetMenuBar (ghMenuBar);
- AppendResMenu (GetMenuHandle (mApple), (ResType) 'DRVR');
- DrawMenuBar ();
- }
- else
- {
- DebugStr ("\pSetUpMenus: Couldn't find menu bar.");
- ghMenuBar = nil;
- goodMenus = false;
- }
-
- return (goodMenus);
- }
-
-
- //-------------------------------------------------------------------------------------------
- //
- void IntializeMenuItems (DocumentPtr theDocument)
- {
- MenuHandle hMenu;
- Str255 menuPrefix = {"\pPicture "},
- itemText,
- numString;
- long item;
- short rsrcID;
- ResType rsrcType;
- Handle hPict;
-
- hMenu = GetMenuHandle(mTexture);
-
- gNumPictures = Count1Resources ('PICT');
-
- /* PICT resources to be used as textures must be numbered starting with kFirstPICTRsrcID */
- SetResLoad (false);
- for (item = 0; item < gNumPictures; item++)
- {
- itemText[0] = 0;
-
- hPict = GetResource ('PICT', kFirstPICTRsrcID + item);
- if (hPict != NULL)
- GetResInfo (hPict, &rsrcID, &rsrcType, itemText);
- else
- break;
-
- if (itemText[0] == 0)
- {
- BlockMove ((Ptr) menuPrefix, (Ptr) itemText, (Size) menuPrefix[0]+1);
- NumToString (item+1, numString);
- itemText[0] += numString[0];
- BlockMove ((Ptr) &numString[1], (Ptr) itemText[itemText[0]+1], (Size) numString[0]);
- }
-
- AppendMenu (hMenu, itemText);
- }
- SetResLoad (true);
-
- gNumPictures = item;
-
- if (theDocument->fTextureType == iNoTexture)
- {
- for (item = iPictureFirst; item < iPictureFirst + gNumPictures; item++)
- DisableItem(hMenu, item);
- }
-
-
- CheckItem (GetMenuHandle (mGeometry), theDocument->fGeometryNum, true);
- CheckItem (hMenu, theDocument->fTextureType, true);
- CheckItem (hMenu, theDocument->fPictureNum, true);
- }
-
-
- //-------------------------------------------------------------------------------------------
- //
- void MainEventLoop()
- {
- EventRecord event;
- WindowPtr window;
- short thePart;
- Rect screenRect, updateRect;
- Point aPoint = {100, 100};
-
-
- while( !gQuitFlag )
- {
- if (WaitNextEvent( everyEvent, &event, 0, nil ))
- {
-
- switch (event.what) {
- case mouseDown:
-
- thePart = FindWindow( event.where, &window );
-
- switch( thePart ) {
- case inMenuBar:
- DoMenuCommand (MenuSelect (event.where));
- break;
-
- case inSysWindow:
- SystemClick (&event, window);
- break;
-
- case inDrag:
- screenRect = (**GetGrayRgn()).rgnBBox;
- DragWindow( window, event.where, &screenRect );
- break ;
-
- case inContent:
- if (window != FrontWindow())
- SelectWindow( window );
- DoPicking(&event);
- break ;
-
- case inGoAway:
- if (TrackGoAway( window, event.where )) {
- DisposeWindow ( window );
- gQuitFlag = true;
- }
- break ;
-
- default:
- case inGrow:
- case inZoomIn:
- case inZoomOut:
- break ;
- }
- break ;
-
-
- case updateEvt:
- window = (WindowPtr)event.message;
- updateRect = (**(window->visRgn)).rgnBBox;
- SetPort( window ) ;
- BeginUpdate( window );
- DocumentDraw3DData( &gDocument ) ;
- EndUpdate( window );
- break ;
-
- case keyDown:
- case autoKey:
- HandleKeyPress(&event);
- break;
-
- case diskEvt:
- if ( HiWord(event.message) != noErr )
- (void) DIBadMount(aPoint, event.message);
- break;
-
- case osEvt:
- case activateEvt:
- break;
-
-
- }
- }
- else {
- // we received a null event, rotate the cube
- TQ3Matrix4x4 tmp;
- Rect theRect = ((GrafPtr)gMainWindow)->portRect ;
-
- SetPort((GrafPtr)gMainWindow) ;
- Q3Matrix4x4_SetRotate_XYZ(&tmp, 0.1, 0.12, 0.08);
- Q3Matrix4x4_Multiply(&gDocument.fRotation, &tmp, &gDocument.fRotation);
-
- InvalRect( &theRect ) ;
- }
- }
- }
-
-
- //-------------------------------------------------------------------------------------------
- //
- void HandleKeyPress(EventRecord *pEvent)
- {
- char charCode;
-
- charCode = pEvent->message & charCodeMask;
-
- if (pEvent->modifiers & btnState)
- {
- /* Button is UP with a key */
- if (pEvent->modifiers & cmdKey)
- {
- DoMenuCommand (MenuKey (charCode));
- }
- }
- else
- {
- /* Button is DOWN with a key */
- }
- }
-
-
- //-------------------------------------------------------------------------------------------
- //
- void DoAboutBox (void)
- {
- DialogPtr theDialog;
- short itemHit;
-
- theDialog = GetNewDialog(kDialogRsrcID, nil, (WindowPtr)-1);
- if (theDialog == nil)
- return;
-
- do
- {
- ModalDialog (nil, &itemHit);
- }
- while (itemHit != ok);
-
- DisposeDialog (theDialog);
- }
-
-
- //-------------------------------------------------------------------------------------------
- //
- void DoMenuCommand (long menuResult)
- {
- short menuID,
- itemNumber;
-
- if (! menuResult)
- return;
-
- menuID = HiWord (menuResult);
- itemNumber = LoWord (menuResult);
-
- switch (menuID)
- {
- case mApple:
- switch (itemNumber)
- {
- case iAbout:
- DoAboutBox();
- break;
-
- default:
- {
- MenuHandle hMenu;
- Str255 deskAccName;
- GrafPtr oldPort;
-
- hMenu = GetMenuHandle (menuID);
- if (hMenu != nil)
- {
- GetPort (&oldPort);
-
- GetMenuItemText (hMenu, itemNumber, deskAccName);
- (void) OpenDeskAcc (deskAccName);
- SetPort (oldPort);
- }
- }
- break;
- }
- break;
-
- case mFile:
- switch (itemNumber)
- {
- case iNew: break;
- case iOpen: break;
- case iClose: break;
-
- case iQuit:
- gQuitFlag = true;break;
-
- default: SysBeep(1);break;
- }
- break;
-
- case mEdit:
- if (! SystemEdit (itemNumber - 1))
- switch (itemNumber)
- {
- case iUndo: break;
- case iCut: break;
- case iCopy: break;
- case iPaste: break;
- case iClear: break;
- }
- break;
-
- case mGeometry:
- if (itemNumber != gDocument.fGeometryNum)
- {
- CheckItem (GetMenuHandle (mGeometry), gDocument.fGeometryNum, false);
- gDocument.fGeometryNum = itemNumber;
- CheckItem (GetMenuHandle (mGeometry), gDocument.fGeometryNum, true);
- ChangeGeometry (&gDocument);
- }
- break;
-
- case mTexture:
- if (itemNumber >= iNoTexture && itemNumber <= iFaceTexture)
- {
- if (itemNumber != gDocument.fTextureType)
- {
- long item;
-
- if (gDocument.fTextureType == iNoTexture)
- {
- for (item = iPictureFirst; item < iPictureFirst + gNumPictures; item++)
- EnableItem(GetMenuHandle (menuID), item);
- }
- else
- if (itemNumber == iNoTexture)
- {
- for (item = iPictureFirst; item < iPictureFirst + gNumPictures; item++)
- DisableItem(GetMenuHandle (menuID), item);
- }
-
- CheckItem (GetMenuHandle (mTexture), gDocument.fTextureType, false);
- gDocument.fTextureType = itemNumber;
- CheckItem (GetMenuHandle (mTexture), gDocument.fTextureType, true);
- ChangeGeometry (&gDocument);
- }
- }
- else
- if (itemNumber >= iPictureFirst && itemNumber <= iPictureFirst + gNumPictures - 1)
- {
- if (itemNumber != gDocument.fPictureNum)
- {
- CheckItem (GetMenuHandle (mTexture), gDocument.fPictureNum, false);
- gDocument.fPictureNum = itemNumber;
- CheckItem (GetMenuHandle (mTexture), gDocument.fPictureNum, true);
- ChangeGeometry (&gDocument);
- }
- }
- break;
-
- default:
- break;
-
- } /* switch (menuID) */
-
- HiliteMenu (0);
- }
-
-
- //-------------------------------------------------------------------------------------------
- //
- void SetCameraLocation (TQ3ViewObject view, float x, float y, float z)
- {
- TQ3CameraObject camera;
- TQ3CameraData cameraData;
-
- Q3View_GetCamera(view, &camera);
- if (camera != nil)
- {
- Q3Camera_GetData(camera, &cameraData);
- Q3Point3D_Set(&cameraData.placement.cameraLocation, x, y, z);
- Q3Camera_SetData(camera, &cameraData);
- Q3Object_Dispose(camera);
- }
- }
-
-
- //-------------------------------------------------------------------------------------------
- //
- void ChangeGeometry (DocumentPtr theDocument)
- {
- TQ3Status status;
- TQ3Object object;
- TQ3GroupPosition position;
- unsigned long triGridLibNum;
-
- if (theDocument->fModel == nil)
- return;
-
- status = Q3Group_GetFirstPositionOfType(theDocument->fModel, kQ3ShapeTypeGeometry, &position);
- if (status == kQ3Success && position != nil)
- {
- object = Q3Group_RemovePosition(theDocument->fModel, position);
- Q3Object_Dispose(object);
- object = NULL;
- }
-
- switch (theDocument->fTextureType)
- {
- case iNoTexture: triGridLibNum = (theDocument->fGeometryNum-1) + kGeometryLibraryRange_Simple; break;
- case iGeometryTexture: triGridLibNum = (theDocument->fGeometryNum-1) + kGeometryLibraryRange_UVGeoAttributes; break;
- case iFaceTexture: triGridLibNum = (theDocument->fGeometryNum-1) + kGeometryLibraryRange_UVFaceAttributes;break;
- }
- object = NewLibraryTriGrid(triGridLibNum);
- if (object == NULL)
- return;
- Q3Group_AddObject (theDocument->fModel, object);
-
- /* Add diffuse color if no texture */
- if (theDocument->fTextureType == iNoTexture)
- {
- TQ3AttributeSet attrSet;
- TQ3ColorRGB rgbColor;
-
- attrSet = Q3AttributeSet_New();
- if (attrSet != NULL)
- {
- Q3ColorRGB_Set(&rgbColor, 0.0, 0.75, 0.75);
- status = Q3AttributeSet_Add(attrSet, kQ3AttributeTypeDiffuseColor, &rgbColor);
- if (status == kQ3Success)
- {
- Q3Geometry_SetAttributeSet(object, attrSet);
- Q3Object_Dispose(attrSet);
- }
- }
- }
- else
- /* Add texture shader */
- AddResourceTextureToGroup(theDocument->fPictureNum - iPictureFirst + kFirstPICTRsrcID, theDocument->fModel);
-
- Q3Object_Dispose(object);
-
- /* (These cameral locations could be calculated) */
- switch (theDocument->fGeometryNum)
- {
- case iFlat: SetCameraLocation (theDocument->fView, 0.0, 0.0, 4.0); break;
- case iTorus: SetCameraLocation (theDocument->fView, 0.0, 0.0, 10.0); break;
- case iWaveyTorus: SetCameraLocation (theDocument->fView, 0.0, 0.0, 10.0); break;
- case iSplash: SetCameraLocation (theDocument->fView, 0.0, 0.0, 25.0); break;
- case iSphere: SetCameraLocation (theDocument->fView, 0.0, 0.0, 7.0); break;
- case iCone: SetCameraLocation (theDocument->fView, 0.0, 0.0, 9.0); break;
- case iPipe: SetCameraLocation (theDocument->fView, 0.0, 0.0, 10.0); break;
- case iSteps: SetCameraLocation (theDocument->fView, 0.0, 0.0, 30.0); break;
- case iSpring: SetCameraLocation (theDocument->fView, 0.0, 0.0, 11.0); break;
- }
- }
-
-
- //-------------------------------------------------------------------------------------------
- //
- void DoPicking(EventRecord *event)
- {
- Point screenPoint;
- TQ3WindowPointPickData withData;
- unsigned long numPicked;
- TQ3PickObject pickObject;
- TQ3Status status;
- TQ3ViewStatus viewStatus;
-
- withData.data.sort = kQ3PickSortNone;
- withData.data.numHitsToReturn= kQ3ReturnAllHits;
- withData.data.mask = kQ3PickDetailMaskObject;
-
- screenPoint = event->where;
- GlobalToLocal (&screenPoint);
- withData.point.x = screenPoint.h;
- withData.point.y = screenPoint.v;
-
- withData.vertexTolerance = withData.edgeTolerance = 2.0;
-
- pickObject = Q3WindowPointPick_New(&withData);
-
- status = Q3View_StartPicking(gDocument.fView, pickObject);
- if (status == kQ3Failure)
- debugstr ("DoPicking: Q3View_StartPicking failed.");
- do {
- status = Q3DisplayGroup_Submit(gDocument.fModel, gDocument.fView);
- if (status == kQ3Failure)
- debugstr ("DoPicking: Q3View_StartPicking failed.");
-
- viewStatus = Q3View_EndPicking(gDocument.fView);
- } while (viewStatus == kQ3ViewStatusRetraverse);
-
- if (viewStatus != kQ3ViewStatusDone)
- debugstr ("DoPicking: Q3View_EndPicking failed.");
-
-
- if (Q3Pick_GetNumHits(pickObject, &numPicked) && (numPicked != 0)) {
- SetCursor(*GetCursor(plusCursor));
- SysBeep(1);
- } else {
- SetCursor(&qd.arrow);
- }
-
- Q3Object_Dispose(pickObject);
- }
-